package cn.monkey.transport.core;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public final class ReactiveCombinedExchangeFactory<C, EXCHANGE extends Exchange> implements ReactiveExchangeFactory<C, EXCHANGE> {

    private final Mono<ReactiveExchangeFactory<C, EXCHANGE>> factory;

    @SafeVarargs
    public ReactiveCombinedExchangeFactory(ReactiveExchangeFactory<C, EXCHANGE>... factories) {
        this.factory = Flux.fromArray(factories)
                .reduce((f1, f2) -> ((key, exchange, c) -> {
                    return f1.apply(key, exchange, c).flatMap(e -> f2.apply(key, e, c));
                }));
    }

    @Override
    public Mono<EXCHANGE> apply(String key, Exchange exchange, C c) {
        return this.factory.flatMap(f -> f.apply(key, exchange, c));
    }
}
